package com.twu.biblioteca;

import java.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;

import static java.lang.System.*;

class EndOfStreamSignal implements Serializable {}
class Movie implements Serializable
{
    private int id;
    private String name;
    private String director;
    private int rating;
    private int year;
    public Movie(int id,String name,String director,int rating,int year )
    {
        this.director=director;
        this.name=name;
        this.id=id;
       this.rating=rating;
        this.year=year;

    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public int getRating() {
        return rating;
    }

    public int getYear() {
        return year;
    }

    public String getDirector() {
        return director;
    }
}
class Transaction implements Serializable
{
    private User user;
    private Book book;
    Transaction(User u,Book b)
    {
        this.user=u;
        this.book=b;
    }

    public Book getBook() {
        return book;
    }

    public User getU() {
        return user;
    }
}
class User implements Serializable
{
    private String lNumber;
    private String password;
    private String name;
    private String email;
    private String phone;

    public String getlNumber()
    {
        return lNumber;
    }

    public String getEmail() {
        return email;
    }

    public String getName() {
        return name;
    }

    public String getPhone() {
        return phone;
    }

    public String getPassword() {
        return password;
    }

    public User(String name,String email,String phone,String lNumber,String password)
    {
        this.name=name;
        this.email=email;
        this.phone=phone;
        this.lNumber=lNumber;
        this.password=password;

    }




}
class Book implements Serializable
{


    int bookid;
    String title;
    String author;
    int year;
    public Book(int bookid,String title,String author,int year)
    {
        this.author=author;
        this.bookid=bookid;
        this.title=title;
        this.year=year;

    }
    public int getBookid()
    {
        return bookid;

    }
    public int getYear()
    {
        return year;
    }
    public String getTitle()
    {
        return title;
    }
    public String getAuthor()
    {
        return author;
    }
}

public class BibliotecaApp {
    static User u=null;

    static ArrayList<Book> availableBook = new ArrayList<Book>();
    static ArrayList<Book> checkedBook = new ArrayList<Book>();

    public static void main(String[] args) throws Exception {
        welcome();

        mainMenu();

    }


    public static void mainMenu() throws Exception {
        while (true) {
            System.out.print("\n\n\n\n\n");
            System.out.println("                                     Menu");
            System.out.println("1. List Books");
            System.out.println("2. Checkout a Book");
            System.out.println("3. Return a Book");
            System.out.println("4. Quit");
            if(u==null)
            System.out.println("5. Login");
            else
            System.out.println("5. User Details");
            System.out.println("6. List Movies");
            System.out.println("7. checkout a Movie");
            System.out.print("\n\n");
            System.out.println("Enter your choice : ");
            BufferedReader stdin = new BufferedReader(new InputStreamReader(in));

            int ch = stdin.read();



            switch (ch) {
                case 49: {
                    listBooks();
                    pressKey();
                    break;
                }
                case 50: {
                    if(u==null)
                        System.out.println("Login first..");
                    else
                    {
                        System.out.println("Enter the book id to be checked..");
                        Scanner sin = new Scanner(System.in);
                        int c = Integer.parseInt(sin.nextLine());
                        if (isChecked(c) == 1)

                            System.out.println("Book not available");
                        else {
                            Book book = findBook(c);
                            if (book != null) {
                                checkBook(book);
                                addTransaction(u,book);
                            }
                            else
                                System.out.println("Wrong id...");
                        }
                    }


                    pressKey();
                    break;
                }
                case 51: {
                    if(u==null)
                        System.out.println("Login first..");
                    else {
                        System.out.println("Enter the book id to be returned..");
                        Scanner sin = new Scanner(System.in);
                        int c = Integer.parseInt(sin.nextLine());
                        if (isChecked(c) == 1) {
                            Book book = findBook(c);
                            if (book != null) {

                                Transaction t=removeTransaction(u,book);
                                if(t==null)
                                    System.out.println("Wrong user returning the book...");
                                else
                                    returnBook(book);

                            }
                            else
                                System.out.println("Wrong Book Id...");
                        } else
                            System.out.println("No book with this id to be returned");
                    }

                    pressKey();
                    break;
                }
                case 52: {
                    System.exit(0);
                    pressKey();
                    break;
                }
                case 53:
                {if (u==null)
                {
                    Scanner scanner=new Scanner(System.in);
                            System.out.println("Enter Library No (xxx-xxxx) :");
                    String no=scanner.nextLine();
                    System.out.println("Enter Password :");
                    String pass=scanner.nextLine();
                    u=findUser(no,pass);
                }
                    else
                {
                    System.out.println("Name  :"+u.getName());
                    System.out.println("Phone  :"+u.getPhone());
                    System.out.println("Email  :"+u.getEmail());

                }

                    break;
                }
                case 54: {
                    listMovies();
                    pressKey();
                    break;
                }
                case 55:
                {
                    System.out.println("Enter the Movie id to be checked..");
                    Scanner sin = new Scanner(System.in);
                    int c = Integer.parseInt(sin.nextLine());
                    if (isCheckedMovie(c) == 1)

                        System.out.println("Movie not available");
                    else {
                        Movie m = findMovie(c);
                        if (m != null) {
                            checkMovie(m);
                        }
                        else
                            System.out.println("Wrong id...");
                    }
                    break;
                }
                default: {
                    invalidMenu();
                    break;
                }
            }


        }


    }

    private static void checkMovie(Movie m) throws Exception{
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("temp.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream("CheckedMovie.ser");
            try {
                ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
                copyfile(inputStream, objectOutputStream);
                inputStream.close();

            }catch (Exception e){}

            System.out.println("\nchecking  " + m.getId());

            objectOutputStream.writeObject(m);


            objectOutputStream.close();

            System.out.println("Done");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        FileOutputStream fileOutputStream = new FileOutputStream("CheckedMovie.ser");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        FileInputStream fileInputStream = new FileInputStream("temp.ser");
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
        copyfile(inputStream, objectOutputStream);
        objectOutputStream.close();
        inputStream.close();
    }

    private static Movie findMovie(int c) {
        try {
            FileInputStream fout = new FileInputStream("Movie.ser");

            ObjectInputStream oos = new ObjectInputStream(fout);

            Movie b;

            while (true) {


                Object o = oos.readObject();
                if (o instanceof EndOfStreamSignal)
                    break;
                b = (Movie) o;
                if (b.getId() == c) {
                    return b;

                }


            }
            oos.close();
        } catch (Exception ex) {

        }
        return null;


    }

    private static int isCheckedMovie(int c) {
        try {
            FileInputStream fout = new FileInputStream("CheckedMovie.ser");
            ObjectInputStream oos = new ObjectInputStream(fout);


            while (true) {


                Object o = null;
                o = oos.readObject();
                if (o instanceof EndOfStreamSignal || o == null)
                    break;
                Movie b = (Movie) o;
                if (b.getId() == c) {

                    return 1;
                }

            }
            oos.close();
        } catch (Exception ex) {

        }
        return 0;
    }

    private static void listMovies() {
        System.out.format("%-10s    %-30s    %-30s    %-10s    %-10s", "id", "Title", "Author", "Year","Rating");
        System.out.println("\n_____________________________________________________________________________________________________________________________________________________\n");
        try {
            FileInputStream fout = new FileInputStream("Movie.ser");
            ObjectInputStream oos = new ObjectInputStream(fout);


            while (true) {


                Object o = oos.readObject();
                if (o instanceof EndOfStreamSignal)
                    break;
                Movie b = (Movie) o;
                if (isCheckedMovie(b.getId()) == 0) {
                    System.out.format("%-10d    %-40s    %-30s    %-10d    %-10d", b.getId(), b.getName(), b.getDirector(), b.getYear(),b.getRating());
                    System.out.println("\n__________________________________________________________________________________________________________________________________________________\n");

                }


            }
            oos.close();
        } catch (Exception ex) {

        }



    }


    private static User findUser(String no, String pass) {

    try {
        FileInputStream fout = new FileInputStream("User.ser");

        ObjectInputStream oos = new ObjectInputStream(fout);

        User u=null;

        while (true) {


            User o = (User)oos.readObject();
            if (o==null)
                break;
            u = (User) o;
            if (u.getlNumber().equals(no) && u.getPassword().equals(pass)) {
                return u;
            }
            else
            {}



        }
        oos.close();
    } catch (Exception ex) {


    }
    System.out.println("Invalid username or password");
    return null;

}



    private static Book findBook(int c) {
        try {
            FileInputStream fout = new FileInputStream("Book.ser");

            ObjectInputStream oos = new ObjectInputStream(fout);

            Book b;

            while (true) {


                Object o = oos.readObject();
                if (o instanceof EndOfStreamSignal)
                    break;
                b = (Book) o;
                if (b.getBookid() == c) {
                    return b;

                }


            }
            oos.close();
        } catch (Exception ex) {

        }
        return null;


    }


    private static void invalidMenu() throws Exception {
        System.out.println("Select a valid option...");
        System.out.println("\nPress a key to continue");

        pressKey();
        mainMenu();

    }


    public static void welcome() throws Exception {
        printStar();
        printStar();
        System.out.print("\n\n\n\n\n");
        System.out.println("                       Welcome To Banglore Public Library                             ");
        System.out.println("\n\n\n\n\n");
        System.out.println("Press a key to continue");
        printStar();
        printStar();
        pressKey();

    }


    public static void pressKey() throws Exception {

        BufferedReader stdin = new BufferedReader(new InputStreamReader(in));
        int ch = stdin.read();
        if (ch != -1) {
            return;

        }
    }

    public static int isChecked(int id) {
        try {
            FileInputStream fout = new FileInputStream("Checked.ser");
            ObjectInputStream oos = new ObjectInputStream(fout);


            while (true) {


                Object o = null;
                o = oos.readObject();
                if (o instanceof EndOfStreamSignal || o == null)
                    break;
                Book b = (Book) o;
                if (b.getBookid() == id) {

                    return 1;
                }

            }
            oos.close();
        } catch (Exception ex) {

        }
        return 0;


    }


    public static void listBooks() {
        System.out.format("%-10s    %-30s    %-30s    %-10s", "id", "Title", "Author", "Year");
        System.out.println("\n_____________________________________________________________________________________________________________________________________________________\n");
        try {
            FileInputStream fout = new FileInputStream("Book.ser");
            ObjectInputStream oos = new ObjectInputStream(fout);


            while (true) {


                Object o = oos.readObject();
                if (o instanceof EndOfStreamSignal)
                    break;
                Book b = (Book) o;
                if (isChecked(b.bookid) == 0) {
                    System.out.format("%-10d    %-30s    %-30s    %-10d", b.getBookid(), b.getTitle(), b.getAuthor(), b.getYear());
                    System.out.println("\n__________________________________________________________________________________________________________________________________________________\n");

                }


            }
            oos.close();
        } catch (Exception ex) {

        }


    }


    public static void printStar() {
        for (int y = 0; y < 160; y++)
            System.out.print("*");
        System.out.println();
    }

    public static void checkBook(Book book) throws Exception {
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("temp.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream("Checked.ser");
            try {
                ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
                copyfile(inputStream, objectOutputStream);
                inputStream.close();

            }catch (Exception e){}

            System.out.println("\nchecking  " + book.getBookid());

            objectOutputStream.writeObject(book);


            objectOutputStream.close();

            System.out.println("Done");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        FileOutputStream fileOutputStream = new FileOutputStream("Checked.ser");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        FileInputStream fileInputStream = new FileInputStream("temp.ser");
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
        copyfile(inputStream, objectOutputStream);
        objectOutputStream.close();
        inputStream.close();
    }
    private static void addTransaction(User u, Book book)throws Exception{
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("temp.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream("Transaction.ser");
            try {
                ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
                copyfile(inputStream, objectOutputStream);
                inputStream.close();

            }catch (Exception e){}

            System.out.println("\nAdding transaction for  " + u.getName());

            Transaction t=new Transaction(u,book);
            objectOutputStream.writeObject(t);


            objectOutputStream.close();

            System.out.println("Done");

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        FileOutputStream fileOutputStream = new FileOutputStream("Transaction.ser");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        FileInputStream fileInputStream = new FileInputStream("temp.ser");
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
        copyfile(inputStream, objectOutputStream);
        objectOutputStream.close();
        inputStream.close();


    }


    public static void copyfile(ObjectInputStream in, ObjectOutputStream out) {
        try {



            while (true) {


                Object o = in.readObject();
                if (o instanceof EndOfStreamSignal || o == null)
                    break;

                out.writeObject(o);


            }
        } catch (Exception ex) {

        }


    }
    private static Transaction removeTransaction(User u, Book book)throws Exception{
        Transaction trans=null;
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("temp.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream("Transaction.ser");
            ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
            Transaction t;

            while (true) {


                Object o =inputStream.readObject();
                if (o instanceof EndOfStreamSignal || o == null)
                    break;
                t = (Transaction) o;
                if(t.getBook().getBookid()==book.getBookid()&& t.getU().getlNumber().equals(u.getlNumber()))
                    trans=new Transaction(u,book);

                else

                {
                    objectOutputStream.writeObject(t);


                }

            }
            objectOutputStream.close();
            inputStream.close();



        } catch (Exception ex) {

        }

        if(trans!=null) {
            FileOutputStream fileOutputStream = new FileOutputStream("Transaction.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream("temp.ser");
            ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
            copyfile(inputStream, objectOutputStream);
            objectOutputStream.close();
            inputStream.close();
            System.out.println("SUCESSFULLY REMOVED TRANSACTION...");

        }

        return trans;
    }

    public static void returnBook(Book book) throws Exception{
        try {
            FileOutputStream fileOutputStream = new FileOutputStream("temp.ser");
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream("Checked.ser");
            ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
            Book b;

            while (true) {


                Object o =inputStream.readObject();
                if (o instanceof EndOfStreamSignal || o == null)
                    break;
                b = (Book) o;
                if(b.getBookid()!=book.getBookid())
                    objectOutputStream.writeObject(b);

            }
            objectOutputStream.close();
            inputStream.close();



        } catch (Exception ex) {

        }
        FileOutputStream fileOutputStream = new FileOutputStream("Checked.ser");
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
        FileInputStream fileInputStream = new FileInputStream("temp.ser");
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
        copyfile(inputStream, objectOutputStream);
        objectOutputStream.close();
        inputStream.close();
        System.out.println("SUCESSFULLY RETURNED...");


    }
}
